package com.ruoyi.car.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.ruoyi.car.api.bo.WxLoginBo;
import com.ruoyi.car.api.bo.WxRegisterBo;
import com.ruoyi.car.api.vo.WxLoginVo;
import com.ruoyi.car.config.WxMaProperties;
import com.ruoyi.car.domain.WxUser;
import com.ruoyi.car.enums.WxUserStatus;
import com.ruoyi.car.mapper.WxUserMapper;
import com.ruoyi.car.service.FormatService;
import com.ruoyi.car.service.IWxUserService;
import com.ruoyi.car.service.SmsService;
import com.ruoyi.car.service.login.WxLoginService;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 微信用户Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-03
 */
@Slf4j
@Service
public class WxUserServiceImpl implements IWxUserService {
    @Autowired
    private WxUserMapper wxUserMapper;

    @Autowired
    private WxMaProperties wxMaProperties;

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private WxLoginService wxLoginService;

    @Autowired
    private FormatService formatService;

    @Autowired
    private SmsService smsService;

    /**
     * 查询微信用户
     *
     * @param wxUserId 微信用户主键
     * @return 微信用户
     */
    @Override
    public WxUser selectWxUserByWxUserId(Long wxUserId) {
        return wxUserMapper.selectWxUserByWxUserId(wxUserId);
    }

    /**
     * 查询微信用户列表
     *
     * @param wxUser 微信用户
     * @return 微信用户
     */
    @Override
    public List<WxUser> selectWxUserList(WxUser wxUser) {
        return wxUserMapper.selectWxUserList(wxUser);
    }

    /**
     * 新增微信用户
     *
     * @param wxUser 微信用户
     * @return 结果
     */
    @Override
    public int insertWxUser(WxUser wxUser) {
        this.beforeSave(wxUser);
        wxUser.setCreateTime(DateUtils.getNowDate());
        return wxUserMapper.insertWxUser(wxUser);
    }

    /**
     * 修改微信用户
     *
     * @param wxUser 微信用户
     * @return 结果
     */
    @Override
    public int updateWxUser(WxUser wxUser) {
        this.beforeSave(wxUser);
        wxUser.setUpdateTime(DateUtils.getNowDate());
        return wxUserMapper.updateWxUser(wxUser);
    }

    private void beforeSave(WxUser wxUser) {
        wxUser.setDelFlag(UserStatus.OK.getCode());
        if (StringUtils.isEmpty(wxUser.getAppId())) {
            wxUser.setAppId(wxMaProperties.getConfigs().get(0).getAppid());
        }
        if (Objects.equals(wxUser.getStatus(), WxUserStatus.REGISTER.getStatus())) {
            wxUser.setRegisterTime(new Date());
        }
        //校验手机号phone唯一
        if (StringUtils.isNotEmpty(wxUser.getPhone())) {
            WxUser wxUserByPhone = this.selectWxUserByPhone(wxUser.getPhone());
            if (Objects.nonNull(wxUserByPhone) && !Objects.equals(wxUserByPhone.getWxUserId(), wxUser.getWxUserId())) {
                throw new ServiceException("手机号已存在");
            }
        }
        wxUser.setPassword(SecurityUtils.encryptPassword(wxUser.getPassword()));
    }

    /**
     * 批量删除微信用户
     *
     * @param wxUserIds 需要删除的微信用户主键
     * @return 结果
     */
    @Override
    public int deleteWxUserByWxUserIds(Long[] wxUserIds) {
        return wxUserMapper.deleteWxUserByWxUserIds(wxUserIds);
    }

    /**
     * 删除微信用户信息
     *
     * @param wxUserId 微信用户主键
     * @return 结果
     */
    @Override
    public int deleteWxUserByWxUserId(Long wxUserId) {
        return wxUserMapper.deleteWxUserByWxUserId(wxUserId);
    }

    @Override
    public WxUser selectWxUserByPhone(String phone) {
        WxUser query = new WxUser();
        query.setPhone(phone);
        query.setDelFlag(UserStatus.OK.getCode());
        List<WxUser> wxUsers = this.selectWxUserList(query);
        if (CollectionUtils.isEmpty(wxUsers)) {
            return null;
        }
        return wxUsers.get(0);
    }

    @Override
    public void register(WxRegisterBo wxRegisterBo) {
        //校验验证码
        smsService.checkCode(wxRegisterBo.getPhone(), wxRegisterBo.getVerifyCode());
        WxUser wxUser = new WxUser();
        wxUser.setNickName(wxRegisterBo.getNickName());
        wxUser.setAvatarUrl(wxRegisterBo.getAvatarUrl());
        wxUser.setPhone(wxRegisterBo.getPhone());
        wxUser.setStatus(WxUserStatus.REGISTER.getStatus());
        wxUser.setOpenid(this.tryGetOpenid(wxRegisterBo.getCode()));
        wxUser.setPassword(wxRegisterBo.getPassword());
        this.insertWxUser(wxUser);
    }

    /**
     * 尝试获取openid
     * 在实际业务中，openid暂时没起到什么作用，如果能取到只是保存下
     * @param code
     * @return
     */
    private String tryGetOpenid(String code) {
        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);
            return session.getOpenid();
        } catch (Exception e) {
            log.error("获取openid失败", e);
        }
        return null;

    }

    @Override
    public WxLoginVo login(WxLoginBo wxLoginBo) {
        String token = wxLoginService.wxLogin(wxLoginBo.getPhone(), wxLoginBo.getPassword());
        WxLoginVo loginVo = new WxLoginVo();
        loginVo.setLoginToken(token);
        WxUser wxUser = this.selectWxUserByPhone(wxLoginBo.getPhone());
        if (StringUtils.isNull(wxUser)) {
            throw new ServiceException("登录用户不存在");
        }
        loginVo.setAvatarUrl(formatService.replaceDomainName(wxUser.getAvatarUrl()));
        loginVo.setNickName(wxUser.getNickName());
        return loginVo;
    }

    @Override
    public int countRegister() {
        return wxUserMapper.countByStatus(WxUserStatus.REGISTER.getStatus());
    }
}
